/**
 * 颜色工具类
 * 提供颜色格式转换、调色板生成、颜色分析等功能
 */
class ColorUtils {
  /**
   * HEX转RGB
   * @param {string} hex - HEX颜色值 (#RRGGBB)
   * @returns {object} RGB对象 {r, g, b}
   */
  static hexToRgb(hex) {
    // 移除#号
    hex = hex.replace('#', '');
    
    // 处理3位HEX
    if (hex.length === 3) {
      hex = hex.split('').map(char => char + char).join('');
    }
    
    if (hex.length !== 6) {
      throw new Error('Invalid HEX color format');
    }
    
    const r = parseInt(hex.substr(0, 2), 16);
    const g = parseInt(hex.substr(2, 2), 16);
    const b = parseInt(hex.substr(4, 2), 16);
    
    return { r, g, b };
  }
  
  /**
   * RGB转HEX
   * @param {number} r - 红色值 (0-255)
   * @param {number} g - 绿色值 (0-255)
   * @param {number} b - 蓝色值 (0-255)
   * @returns {string} HEX颜色值
   */
  static rgbToHex(r, g, b) {
    const toHex = (n) => {
      const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
      return hex.length === 1 ? '0' + hex : hex;
    };
    
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
  }
  
  /**
   * RGB转HSL
   * @param {number} r - 红色值 (0-255)
   * @param {number} g - 绿色值 (0-255)
   * @param {number} b - 蓝色值 (0-255)
   * @returns {object} HSL对象 {h, s, l}
   */
  static rgbToHsl(r, g, b) {
    r /= 255;
    g /= 255;
    b /= 255;
    
    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    let h, s, l = (max + min) / 2;
    
    if (max === min) {
      h = s = 0; // 无色
    } else {
      const d = max - min;
      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
      
      switch (max) {
        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
        case g: h = (b - r) / d + 2; break;
        case b: h = (r - g) / d + 4; break;
      }
      h /= 6;
    }
    
    return {
      h: Math.round(h * 360),
      s: Math.round(s * 100),
      l: Math.round(l * 100)
    };
  }
  
  /**
   * HSL转RGB
   * @param {number} h - 色相 (0-360)
   * @param {number} s - 饱和度 (0-100)
   * @param {number} l - 亮度 (0-100)
   * @returns {object} RGB对象 {r, g, b}
   */
  static hslToRgb(h, s, l) {
    h /= 360;
    s /= 100;
    l /= 100;
    
    const hue2rgb = (p, q, t) => {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1/6) return p + (q - p) * 6 * t;
      if (t < 1/2) return q;
      if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
      return p;
    };
    
    let r, g, b;
    
    if (s === 0) {
      r = g = b = l; // 无色
    } else {
      const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      const p = 2 * l - q;
      r = hue2rgb(p, q, h + 1/3);
      g = hue2rgb(p, q, h);
      b = hue2rgb(p, q, h - 1/3);
    }
    
    return {
      r: Math.round(r * 255),
      g: Math.round(g * 255),
      b: Math.round(b * 255)
    };
  }
  
  /**
   * 验证HEX颜色格式
   * @param {string} hex - HEX颜色值
   * @returns {boolean} 是否有效
   */
  static isValidHex(hex) {
    return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex);
  }
  
  /**
   * 验证RGB值
   * @param {number} value - RGB值
   * @returns {boolean} 是否有效
   */
  static isValidRgb(value) {
    return Number.isInteger(value) && value >= 0 && value <= 255;
  }
  
  /**
   * 验证HSL值
   * @param {number} h - 色相
   * @param {number} s - 饱和度
   * @param {number} l - 亮度
   * @returns {boolean} 是否有效
   */
  static isValidHsl(h, s, l) {
    return Number.isInteger(h) && h >= 0 && h <= 360 &&
           Number.isInteger(s) && s >= 0 && s <= 100 &&
           Number.isInteger(l) && l >= 0 && l <= 100;
  }
  
  /**
   * 生成随机颜色
   * @returns {string} 随机HEX颜色
   */
  static randomColor() {
    const letters = '0123456789ABCDEF';
    let color = '#';
    for (let i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
  }
  
  /**
   * 计算颜色亮度
   * @param {string} hex - HEX颜色值
   * @returns {number} 亮度值 (0-255)
   */
  static getLuminance(hex) {
    const rgb = this.hexToRgb(hex);
    // 使用相对亮度公式
    return Math.round(0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b);
  }
  
  /**
   * 判断颜色是否为深色
   * @param {string} hex - HEX颜色值
   * @returns {boolean} 是否为深色
   */
  static isDark(hex) {
    return this.getLuminance(hex) < 128;
  }
  
  /**
   * 获取对比色（黑色或白色）
   * @param {string} hex - HEX颜色值
   * @returns {string} 对比色
   */
  static getContrastColor(hex) {
    return this.isDark(hex) ? '#FFFFFF' : '#000000';
  }
  
  /**
   * 计算两个颜色的对比度
   * @param {string} color1 - 第一个颜色
   * @param {string} color2 - 第二个颜色
   * @returns {number} 对比度比值
   */
  static getContrastRatio(color1, color2) {
    const l1 = this.getLuminance(color1);
    const l2 = this.getLuminance(color2);
    const lighter = Math.max(l1, l2);
    const darker = Math.min(l1, l2);
    return (lighter + 0.05) / (darker + 0.05);
  }
}

/**
 * 调色板生成器
 */
class PaletteGenerator {
  /**
   * 生成单色调色板
   * @param {string} baseColor - 基础颜色
   * @param {number} count - 颜色数量
   * @returns {Array} 颜色数组
   */
  static monochromatic(baseColor, count = 5) {
    const rgb = ColorUtils.hexToRgb(baseColor);
    const hsl = ColorUtils.rgbToHsl(rgb.r, rgb.g, rgb.b);
    const colors = [];
    
    for (let i = 0; i < count; i++) {
      const lightness = Math.max(10, Math.min(90, hsl.l + (i - Math.floor(count/2)) * 20));
      const newRgb = ColorUtils.hslToRgb(hsl.h, hsl.s, lightness);
      colors.push(ColorUtils.rgbToHex(newRgb.r, newRgb.g, newRgb.b));
    }
    
    return colors;
  }
  
  /**
   * 生成类似色调色板
   * @param {string} baseColor - 基础颜色
   * @param {number} count - 颜色数量
   * @returns {Array} 颜色数组
   */
  static analogous(baseColor, count = 5) {
    const rgb = ColorUtils.hexToRgb(baseColor);
    const hsl = ColorUtils.rgbToHsl(rgb.r, rgb.g, rgb.b);
    const colors = [];
    const step = 30; // 色相步长
    
    for (let i = 0; i < count; i++) {
      const hue = (hsl.h + (i - Math.floor(count/2)) * step + 360) % 360;
      const newRgb = ColorUtils.hslToRgb(hue, hsl.s, hsl.l);
      colors.push(ColorUtils.rgbToHex(newRgb.r, newRgb.g, newRgb.b));
    }
    
    return colors;
  }
  
  /**
   * 生成互补色调色板
   * @param {string} baseColor - 基础颜色
   * @returns {Array} 颜色数组
   */
  static complementary(baseColor) {
    const rgb = ColorUtils.hexToRgb(baseColor);
    const hsl = ColorUtils.rgbToHsl(rgb.r, rgb.g, rgb.b);
    const complementHue = (hsl.h + 180) % 360;
    const complementRgb = ColorUtils.hslToRgb(complementHue, hsl.s, hsl.l);
    
    return [
      baseColor,
      ColorUtils.rgbToHex(complementRgb.r, complementRgb.g, complementRgb.b)
    ];
  }
  
  /**
   * 生成三角色调色板
   * @param {string} baseColor - 基础颜色
   * @returns {Array} 颜色数组
   */
  static triadic(baseColor) {
    const rgb = ColorUtils.hexToRgb(baseColor);
    const hsl = ColorUtils.rgbToHsl(rgb.r, rgb.g, rgb.b);
    const colors = [baseColor];
    
    for (let i = 1; i < 3; i++) {
      const hue = (hsl.h + i * 120) % 360;
      const newRgb = ColorUtils.hslToRgb(hue, hsl.s, hsl.l);
      colors.push(ColorUtils.rgbToHex(newRgb.r, newRgb.g, newRgb.b));
    }
    
    return colors;
  }
  
  /**
   * 生成四角色调色板
   * @param {string} baseColor - 基础颜色
   * @returns {Array} 颜色数组
   */
  static tetradic(baseColor) {
    const rgb = ColorUtils.hexToRgb(baseColor);
    const hsl = ColorUtils.rgbToHsl(rgb.r, rgb.g, rgb.b);
    const colors = [baseColor];
    
    for (let i = 1; i < 4; i++) {
      const hue = (hsl.h + i * 90) % 360;
      const newRgb = ColorUtils.hslToRgb(hue, hsl.s, hsl.l);
      colors.push(ColorUtils.rgbToHex(newRgb.r, newRgb.g, newRgb.b));
    }
    
    return colors;
  }
  
  /**
   * 生成分离互补色调色板
   * @param {string} baseColor - 基础颜色
   * @returns {Array} 颜色数组
   */
  static splitComplementary(baseColor) {
    const rgb = ColorUtils.hexToRgb(baseColor);
    const hsl = ColorUtils.rgbToHsl(rgb.r, rgb.g, rgb.b);
    const colors = [baseColor];
    
    // 分离互补色：基础色相±150度
    const hues = [(hsl.h + 150) % 360, (hsl.h + 210) % 360];
    
    hues.forEach(hue => {
      const newRgb = ColorUtils.hslToRgb(hue, hsl.s, hsl.l);
      colors.push(ColorUtils.rgbToHex(newRgb.r, newRgb.g, newRgb.b));
    });
    
    return colors;
  }
}

/**
 * 图片颜色提取器
 */
class ColorExtractor {
  /**
   * 从图片数据中提取主要颜色
   * @param {ImageData} imageData - 图片数据
   * @param {number} colorCount - 提取颜色数量
   * @returns {Array} 颜色数组
   */
  static extractColors(imageData, colorCount = 5) {
    const pixels = imageData.data;
    const colorMap = new Map();
    
    // 采样像素（每隔10个像素采样一次以提高性能）
    for (let i = 0; i < pixels.length; i += 40) { // 4 * 10 = 40
      const r = pixels[i];
      const g = pixels[i + 1];
      const b = pixels[i + 2];
      const a = pixels[i + 3];
      
      // 跳过透明像素
      if (a < 128) continue;
      
      // 量化颜色以减少颜色数量
      const quantizedR = Math.floor(r / 32) * 32;
      const quantizedG = Math.floor(g / 32) * 32;
      const quantizedB = Math.floor(b / 32) * 32;
      
      const colorKey = `${quantizedR},${quantizedG},${quantizedB}`;
      colorMap.set(colorKey, (colorMap.get(colorKey) || 0) + 1);
    }
    
    // 按出现频率排序
    const sortedColors = Array.from(colorMap.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, colorCount)
      .map(([colorKey]) => {
        const [r, g, b] = colorKey.split(',').map(Number);
        return ColorUtils.rgbToHex(r, g, b);
      });
    
    return sortedColors;
  }
  
  /**
   * 使用K-means算法提取主要颜色
   * @param {ImageData} imageData - 图片数据
   * @param {number} k - 聚类数量
   * @returns {Array} 颜色数组
   */
  static extractColorsKMeans(imageData, k = 5) {
    const pixels = [];
    const data = imageData.data;
    
    // 采样像素
    for (let i = 0; i < data.length; i += 40) {
      if (data[i + 3] >= 128) { // 非透明像素
        pixels.push([data[i], data[i + 1], data[i + 2]]);
      }
    }
    
    if (pixels.length === 0) return [];
    
    // 初始化聚类中心
    const centroids = [];
    for (let i = 0; i < k; i++) {
      const randomPixel = pixels[Math.floor(Math.random() * pixels.length)];
      centroids.push([...randomPixel]);
    }
    
    // K-means迭代
    for (let iter = 0; iter < 10; iter++) {
      const clusters = Array(k).fill().map(() => []);
      
      // 分配像素到最近的聚类中心
      pixels.forEach(pixel => {
        let minDistance = Infinity;
        let closestCentroid = 0;
        
        centroids.forEach((centroid, index) => {
          const distance = Math.sqrt(
            Math.pow(pixel[0] - centroid[0], 2) +
            Math.pow(pixel[1] - centroid[1], 2) +
            Math.pow(pixel[2] - centroid[2], 2)
          );
          
          if (distance < minDistance) {
            minDistance = distance;
            closestCentroid = index;
          }
        });
        
        clusters[closestCentroid].push(pixel);
      });
      
      // 更新聚类中心
      clusters.forEach((cluster, index) => {
        if (cluster.length > 0) {
          const avgR = cluster.reduce((sum, pixel) => sum + pixel[0], 0) / cluster.length;
          const avgG = cluster.reduce((sum, pixel) => sum + pixel[1], 0) / cluster.length;
          const avgB = cluster.reduce((sum, pixel) => sum + pixel[2], 0) / cluster.length;
          centroids[index] = [Math.round(avgR), Math.round(avgG), Math.round(avgB)];
        }
      });
    }
    
    // 转换为HEX颜色
    return centroids
      .filter(centroid => centroid.length === 3)
      .map(centroid => ColorUtils.rgbToHex(centroid[0], centroid[1], centroid[2]));
  }
}

module.exports = {
  ColorUtils,
  PaletteGenerator,
  ColorExtractor
};